//这个模块是微信交互，既消息获取和响应素材/文字消息/视频/音乐/链接，
// 这里我用消息关键词做交互，测试素材操作、一些标签和用户信息管理等等
const getRawBody=require('raw-body');  //接收xml流数据响应工具，微信公众号获取XML流数据用到
const contentType=require('content-type');  //报文/网页内容类型识别处理工具。公众号请求数据类型的工具
const parseXml=require('./parsexml');   //将处理xml变为json数据
const templa=require('./views/template')
const request=require('request')
const path=require('path')
const fs=require('fs')
let ffmpeg = require('fluent-ffmpeg');  //系统必须自己安装ffmpeg
const tags=require('./tags').tags
const {mass}=require('./mass')
const {menu}=require('./nav')
const {intelligence}=require('./intelligence')

var Chat=require('./vchat').Wechat

sendContent=async (ctx,opts) => {
    let contentConfig={
        subscribeMsg:'感谢关注公众号，本公司服务于媒体行业',
        phone:'13800138000',
        kefu:"<a href='https://www.baidu.com'>点击进入客服页面</a>",

    }

    let data=await getRawBody(ctx.req,{
        length:ctx.req.headers['content-length'],
        limit:'1mb',
        encoding:contentType.parse(ctx.req).parameters.charset
    })
    // raw-body对koa是没回调，要用await、yield或then。对express是异步带回调的
    let getXmlContent=await parseXml.parseXMLAsync(data).then(async (content)=>{
        //一定要new，因为Wechat是构造函数，否则继承方法无法实现
        var chatObj=await new Chat(opts) //传入config中的配置，进行实例化（即预先执行一次将里面数据跟新）
        let msg=parseXml.formatMsg(content.xml);
        console.log('msg-------------------')
        console.log(msg)
        let XmlContent={}
        let msgType=''
        let filePath=''
        let results=null
        XmlContent.FromUserName=msg.FromUserName;
        XmlContent.ToUserName=msg.ToUserName;
        XmlContent.timeNow = parseInt(new Date().getTime() / 1000);
        let permanentContent=null
        switch (msg.MsgType) {
            case 'image':  //客户端拍照发送、选取相册发送，都会推送image事件，可以获得临时上传地址
                XmlContent.msgType = 'text';//this.msgType是后台发送消息的模板类型
                XmlContent.txt = msg.PicUrl+'\n'+msg.MediaId
                break;
            case 'location':  //客户端发送地理位置，或同意获取后（每五分钟给后台一次）+返回的推送消息
                XmlContent.msgType = 'text';
                XmlContent.txt=`纬度：${msg.Location_X} ;经度：${msg.Location_Y} ; 地址：${msg.Label}`
                break;

            case 'voice':  //语音MsgType
                //这里演示存语音文件在服务器转mp3
                // filePath=path.resolve('./temp02.amr')
                // results=await chatObj.saveTemp(msg.MediaId,filePath)
                // if(results.code!=='001')throw('存语音失败');
                // await (() => {
                //     return new Promise((resolve, reject) => {
                //         let command = ffmpeg('temp02.amr')  //amr转换mp3
                //             .on('end', function() {
                //                 console.log('save succesfully');
                //                 resolve()
                //             })
                //             .on('error', function(err) {
                //                 console.log('an error: ' + err.message);
                //                 reject()
                //             })
                //             .save('temp02.mp3');
                //     })
                // })()
                //下面直接将语音识别结果属性取出（需公众号开启 语音识别）
                XmlContent.msgType = 'text';
                XmlContent.txt =msg.Recognition
                break;
            case 'event':  //事件MsgType
                switch (msg.Event) {
                    case 'subscribe':  //关注事件+返回的推送消息
                        XmlContent.msgType = 'text';//this.msgType是后台发送消息的模板类型
                        XmlContent.txt = contentConfig.subscribeMsg
                        break;
                    case 'CLICK':  //点击事件+返回的推送消息，这里微信返回的是大写
                        switch (msg.EventKey) {  //事件key属性值（创建菜单时配置了
                            case 'sing':
                                XmlContent.msgType = 'text';//this.msgType是后台发送消息的模板类型
                                XmlContent.txt = 'click-sing'
                                break;
                        }
                        break;
                    case 'VIEW':  //跳转网页事件
                        switch (msg.EventKey) {  //由于可能多个事件，但是创建菜单时EventKey是不同的
                            case 'http://www.soso.com/':
                                console.log(msg.EventKey)
                                break;
                        }
                        break;
                    case 'scancode_push':  //扫码事件推送，有扫码事件推送（常用）和带提示扫码事件
                        switch (msg.EventKey) {  //事件key属性值（创建菜单时配置了
                            case 'rselfmenu_02':
                                console.log(msg.ScanCodeInfo);
                                break;
                        }
                        break;
                    case 'location_select':  //发送地理位置事件+返回的推送消息
                        switch (msg.EventKey) {  //事件key属性值（创建菜单时配置了
                            case 'rselfmenu_2_0':
                                console.log('点击地理发送按钮')  //前台是不会有反应也不能发文本
                                break;
                        }
                        break;
                    case 'pic_sysphoto':  //弹出系统拍照发图的事件+返回的推送消息
                        switch (msg.EventKey) {
                            case 'rselfmenu_1_0':
                                console.log(msg.SendPicsInfo)
                                console.log(msg.SendPicsInfo.Count)
                                break;
                        }
                        break;
                    case 'pic_photo_or_album':  //弹出拍照或者相册发图的事件+返回的推送消息
                        switch (msg.EventKey) {
                            case 'rselfmenu_1_1':
                                console.log(msg.SendPicsInfo)
                                console.log(msg.SendPicsInfo.Count)
                                break;
                        }
                        break;
                    case 'pic_weixin':  //弹出微信相册发图器的事件+返回的推送消息
                        switch (msg.EventKey) {
                            case 'rselfmenu_1_2':
                                console.log(msg.SendPicsInfo)
                                console.log(msg.SendPicsInfo.Count)
                                break;
                        }
                        break;
                    case 'view_miniprogram':  //弹出微信小程序事件+返回的推送消息
                        console.log(msg.MenuID)
                        console.log(msg.EventKey)  //这里EventKey与其他不同，这是小程序路径
                        break;
                }
                break;

            case 'text':   //文本MsgType

                switch (msg.Content) {
                    case '网站':
                        XmlContent.msgType = 'text';
                        XmlContent.txt = '<a href="http://err.free-http.svipss.top/dy">点击进入</a>'
                        break;
                    case '客服':
                        XmlContent.msgType = 'text';
                        XmlContent.txt = contentConfig.kefu
                        break;
                    case '电话':
                        XmlContent.msgType = 'text';
                        XmlContent.txt = contentConfig.phone
                        break;
                    case '1':
                        filePath=__dirname+'/2.jpg'
                        XmlContent.msgType = 'image';
                        results=await chatObj.updataPublic(filePath,XmlContent.msgType)
                        if(!results.media_id)throw ('media_id获取失败')
                        XmlContent.mediaId=results.media_id
                        break;
                    case '2':
                        //视频文件别太大（可能服务器网速有关），否则静默错误无应答
                        filePath=__dirname+'/6.mp4'
                        XmlContent.msgType = 'video';
                        results=await chatObj.updataPublic(filePath,XmlContent.msgType)
                        if(!results.media_id)throw ('media_id获取失败')
                        XmlContent.mediaId=results.media_id
                        XmlContent.title='puppeteer视频'
                        XmlContent.description='详情或简介'
                        break;
                    case '3':
                        filePath=__dirname+'/61.jpg'
                        XmlContent.msgType = 'image';
                        //只能传语音不能传音乐文件，所以随便传图片只是为了拿到mediaId，反正url点击能打开就行
                        results=await chatObj.updataPublic(filePath,XmlContent.msgType)
                        XmlContent.msgType = 'music';  //但是回复消息类型要写官方音乐文件模板的music
                        if(!results.media_id)throw ('media_id获取失败')
                        XmlContent.mediaId=results.media_id
                        XmlContent.title='音乐'
                        XmlContent.description='详情或简介'
                        XmlContent.musicUrl='http://ting6.yymp3.net:86/new27/underlover/3.mp3'
                        XmlContent.hqMusicUrl=''
                        break;
                    case '4':
                        filePath=__dirname+'/6.jpg'
                        XmlContent.msgType = 'news';
                        XmlContent.news={  //现在公众号被动回复不能多图文，只能1条
                                title:'图片一',
                                description:'第一个详情或简介',
                                picUrl:'http://img0.imgtn.bdimg.com/it/u=343393585,3876288311&fm=26&gp=0.jpg',
                                url:'https://www.baidu.com'
                            }
                        XmlContent.articleCount=1
                        break;
                    case '5': //permanentImg（上传永久图片
                        filePath=__dirname+'/61.jpg'
                        msgType=XmlContent.msgType = 'image';
                        results=await chatObj.permanentPublic({filePath,msgType})
                        if(!results.media_id)throw ('media_id获取失败')
                        XmlContent.mediaId=results.media_id
                        break;
                    case '51': //permanentImg（上传永久图片）+用media_id交换，获取的是img流对象
                        filePath=__dirname+'/61.jpg'
                        msgType=XmlContent.msgType = 'image';
                        results=await chatObj.permanentPublic({filePath,msgType})
                        permanentContent=await chatObj.permanentMediaId(results.media_id)
                        //（结果是一个流对象可直接pipe(fs.createWriteStream('1.jpg'))存本地）
                        break;
                    case '6':  //permanentVideo（上传永久视频），注意永久视频需要用media_id交换，获取的是url
                        //视频文件别太大（可能服务器网速有关），否则静默错误无应答
                        filePath=__dirname+'/6.mp4'
                        msgType=XmlContent.msgType = 'video';
                        XmlContent.title='puppeteer视频'
                        XmlContent.description='详情或简介'
                        let videoDescription={  //上传永久视频要在form表单加description属性，内容是这种对象
                            "title":XmlContent.title,
                            "introduction":XmlContent.description
                        }
                        videoDescription=JSON.stringify(videoDescription)
                        results=await chatObj.permanentPublic({filePath,msgType,videoDescription})
                        if(!results.media_id)throw ('media_id获取失败')
                        XmlContent.msgType = 'text';
                        permanentContent=await chatObj.permanentMediaId(results.media_id)
                        XmlContent.txt = JSON.stringify(permanentContent)

                        break;
                    case 'news':  //permanentNews（永久素材），用media_id交互，获取的是news设置的newsContent信息
                        filePath=__dirname+'/61.jpg'
                        XmlContent.title='61jpg'
                        XmlContent.description='详情或简介'
                        msgType='thumb'
                        let thumb=await chatObj.permanentPublic({filePath,msgType})
                        await console.log('thumb.media_id',thumb.media_id)
                        //下句是 需要注意的是图文消息里的图片，要用特别接口上传直接换取url而不是上面（上传永久图片）方式
                        let img=await chatObj.permanentPublic({filePath})
                        if(!img.url)throw ('imgUrl获取失败')
                        let newsContent={  //公众号最新改是不能上传多图文，只能单图文
                            "articles": [{
                                "title": "XmlContent.title",
                                "thumb_media_id":thumb.media_id,
                                "author": 'hua',
                                "digest": "XmlContent.description",
                                "show_cover_pic": 1,
                                "content": `<h1>my-vchat</h1><img src="${img.url}"><a href="https://www.baidu.com">dianji</a>`,
                                // "content": "https://www.baidu.com",
                                "content_source_url": 'https://www.baidu.com',
                                "need_open_comment":1,
                                "only_fans_can_comment":1
                            }]
                        }
                        results=await chatObj.permanentPublic({newsContent})
                        await console.log(results)
                        XmlContent.msgType = 'text';
                        //下面这句是封装了 获取素材。音频和image获取的是数据流，视频he缩略图是url，图文是内容
                        permanentContent=await chatObj.permanentMediaId(results.media_id)
                        XmlContent.txt = JSON.stringify(permanentContent)
                        break;
                    case '7':
                        let Count=await chatObj.getPermanentCount()  //得到所有素材总数
                        XmlContent.msgType = 'text';
                        XmlContent.txt = JSON.stringify(Count)
                        break;
                    default:
                        XmlContent.msgType = 'text';
                        if(msg.Content.match(/^delId(.*)/)){   //删除指定素材
                            let mediaId=msg.Content.replace('delId','')
                            let delStatus=await chatObj.delMedia(mediaId)
                            XmlContent.txt = JSON.stringify(delStatus)
                        }else if(msg.Content.match(/^cx(.*)/)){  //查询指定类型素材列表
                            let cxType=msg.Content.replace('cx','')
                            let postBody={
                                "type":cxType,
                                "offset":0,  //从第几开始获取
                                "count":2   //获取几条数据，最大写20
                            }
                            let list=await chatObj.getList(postBody) //获取某类型数据列表
                            console.log(list)
                            XmlContent.txt = JSON.stringify(list)
                        }else if(msg.Content.match(/^newTag(.*)/)){
                            let tag=msg.Content.replace('newTag','')
                            const postData={
                                "tag" : {
                                    "name" : tag  //标签名
                                }
                            }
                            results=await tags.tagsOpt('newTag',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^getTags(.*)/)){

                            results=await tags.tagsOpt('getTags')
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^editTag(.*)/)){
                            let splitMsg=msg.Content.match(/^editTag([0-9]{3,5})/)
                            let id=splitMsg[1]
                            let tagName=msg.Content.split('+')
                            const postData={"tag" : {     "id" : id,     "name" : tagName[1]   }}
                            results=await tags.tagsOpt('editTag',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^delTag(.*)/)){
                            let id=msg.Content.replace('delTag','')
                            const postData={"tag" : {"id" : id}}
                            results=await tags.tagsOpt('delTag',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^getTagUsers(.*)/)){
                            let id=msg.Content.replace('getTagUsers','')
                            const postData={"tagid" : id,   "next_openid":""}
                            results=await tags.tagsOpt('getTagUsers',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^setUsersTag(.*)/)){
                            let splitMsg=msg.Content.match(/^setUsersTag([0-9]{3,5})/)
                            let id=splitMsg[1]
                            let openId=msg.Content.split('+')
                            const postData={
                                "openid_list" : [//粉丝列表
                                    openId[1]  //这里是用户openId
                                ],
                                "tagid" : id
                            }
                            results=await tags.tagsOpt('setUsersTag',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^delUsersTag(.*)/)){
                            let splitMsg=msg.Content.match(/^delUsersTag([0-9]{3,5})/)
                            let id=splitMsg[1]
                            let openId=msg.Content.split('+')
                            const postData={
                                "openid_list" : [//粉丝列表
                                    // openId[1]  //这里是用户openId
                                    openId[1]
                                ],
                                "tagid" : id
                            }
                            results=await tags.tagsOpt('delUsersTag',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^usersList(.*)/)){  //获取所有已关注用户列表
                            let splitMsg=msg.Content.match(/^usersList([0-9]*)/)
                            let id=splitMsg[1]||1  //没有传值就默认1
                            const postData={
                                next_openid:id
                            }
                            results=await tags.tagsOpt('usersList',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^userDetails(.*)/)){
                            let splitMsg=msg.Content.match(/^userDetails\+(.*)/)
                            let id=splitMsg[1]
                            const postData={
                                "user_list":
                                    [{
                                        "openid": id,
                                        "lang": "zh_CN"
                                    }]   //可以批量获取多个
                            }
                            results=await tags.tagsOpt('userDetails',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^ticket(.*)/)){
                            const postData={   //临时公众号二维码链接参数，永久和临时区别就是提交参数不同
                                "expire_seconds": 604800,
                                "action_name": "QR_SCENE",
                                "action_info": {"scene": {"scene_id": 123}}
                            }
                            // const postData={   //永久公众号二维码链接参数
                            //     "action_name": "QR_LIMIT_SCENE",
                            //     "action_info": {"scene": {"scene_id": 2}}
                            // }
                            results=await tags.tagsOpt('ticket',postData)
                            // 注意下面这个地址与上面不一样是 mp.weixin.xxx
                            const showTicket="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+results.ticket;
                            let filePath=path.resolve('ticket.png')

                            return new Promise((resolve, reject) => {
                                request(showTicket).pipe(fs.createWriteStream(filePath)).once('close',async (err,XmlContent)=>{
                                    let ticket={}
                                    ticket.FromUserName=msg.FromUserName;
                                    ticket.ToUserName=msg.ToUserName;
                                    ticket.timeNow = parseInt(new Date().getTime() / 1000);
                                    ticket.msgType='image'
                                    let upResult=await chatObj.updataPublic(filePath,ticket.msgType)
                                    if(!upResult.media_id)throw ('media_id获取失败')
                                    ticket.msgType='image'
                                    ticket.mediaId=upResult.media_id
                                    resolve(ticket)
                                })
                            })

                        }else if(msg.Content.match(/^massNew(.*)/)){
                            let splitMsg=msg.Content.match(/^massNew\+(.*)/)
                            let id=splitMsg[1]-''
                            const postData={
                                tagId:id
                            }
                            results=await mass.massOpt('massNew',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^newMenu/)){
                            results=await menu.menuOpt('newMenu')
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^delMenu/)){
                            results=await menu.menuOpt('delMenu')
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^findMenu/)){
                            results=await menu.menuOpt('findMenu')
                            XmlContent.txt = JSON.stringify(results)
                        }else if(msg.Content.match(/^semantic/)){
                            const postData={
                                query:"广东机票",
                                city:"广东",
                                uid:msg.FromUserName
                            }
                            results=await intelligence.intelligenceOpt('semantic',postData)
                            XmlContent.txt = JSON.stringify(results)
                        }else{
                            XmlContent.txt = '输入指令bu正确'
                        }

                }
                break;
        }
        return XmlContent  //返回xml内容对象给getXmlContent接收
    }).catch(err=>{throw err});
    ctx.status=200;
    ctx.set('Content-Type','application/xml');
    ctx.body=templa(getXmlContent)

}
module.exports=sendContent